// SkinButton.cpp : implementation file
//

#include "stdafx.h"
#include "SkinButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CSkinButton

IMPLEMENT_DYNAMIC(CSkinButton, CButton)

CSkinButton::CSkinButton()
		: m_pImgNormal(m_pBitmaps[0]),
		m_pImgOver(m_pBitmaps[1]),
		m_pImgDown(m_pBitmaps[2]),
		m_pImgDisabled(m_pBitmaps[3])
		, m_pCurImg(NULL)
{
	ZeroMemory (m_pBitmaps, sizeof(m_pBitmaps));
	m_CheckedButton = m_MouseOnButton = FALSE;
}

CSkinButton::~CSkinButton()
{
	for (int i = 0; i < sizeof(m_pBitmaps) / sizeof(m_pBitmaps[0]); i++) {
		delete m_pBitmaps[i];
		m_pBitmaps[i] = NULL;
	}
}

//=============================================================================
BOOL CSkinButton::CreateInternal( const RECT& rect, CWnd* pParentWnd, UINT nID )
{
	CRect rt(rect);
	if (rt.Width() < 1 && rt.Height() < 1) {
		ASSERT(m_pImgNormal);
		rt.right = rt.left + m_pImgNormal->GetWidth();
		rt.bottom = rt.top + m_pImgNormal->GetHeight();
	}
	if (!CButton::Create(m_strCommandName, BS_OWNERDRAW|BS_FLAT | WS_VISIBLE, rt, pParentWnd, nID)) {
		return FALSE;
	}

	m_ctrlTooltip.Create(this);

	return TRUE;
}

//=============================================================================
BOOL CSkinButton::LoadSkinImage( LPCTSTR lpszFilename )
{
	Gdiplus::Bitmap bmControl(lpszFilename);
	const INT cxImg = bmControl.GetWidth();
	const INT cyImg = bmControl.GetHeight();
	if (cxImg < 1 && cyImg < 1)
		return FALSE;

	const INT cxCtrl = cxImg / 4;
	INT xPos = 0;
	VERIFY (m_pImgNormal = bmControl.Clone(xPos, 0, cxCtrl, cyImg, PixelFormatDontCare));
	VERIFY (m_pImgOver = bmControl.Clone(xPos += cxCtrl, 0, cxCtrl, cyImg, PixelFormatDontCare));
	VERIFY (m_pImgDown = bmControl.Clone(xPos += cxCtrl, 0, cxCtrl, cyImg, PixelFormatDontCare));
	VERIFY (m_pImgDisabled = bmControl.Clone(xPos += cxCtrl, 0, cxCtrl, cyImg, PixelFormatDontCare));

	return TRUE;
}

//=============================================================================
void CSkinButton::DrawIt( Gdiplus::Bitmap* pbmWnd, const RECT& rect )
{
	ASSERT(pbmWnd);
	ASSERT(m_pImgNormal);

	SetWindowPos(NULL, 
		rect.left - m_cxBorder,
		rect.top - m_cyBorder, 
		0, 0, SWP_NOSIZE|SWP_NOREDRAW);
	//MoveWindow(rect.left, rect.top, m_pImgNormal->GetWidth(), m_pImgNormal->GetHeight(), FALSE);
	// Test [6/1/2008 Dean]
	Gdiplus::Graphics graphic(pbmWnd);
	if ( NULL == m_pCurImg ) {
		m_pCurImg = m_pImgNormal;		
	}

	graphic.DrawImage(m_pCurImg, rect.left, rect.top, m_pCurImg->GetWidth(), m_pCurImg->GetHeight());
	// end test
}

//=============================================================================
BEGIN_MESSAGE_MAP(CSkinButton, CButton)
	ON_WM_KILLFOCUS()
	ON_WM_MOUSEMOVE()
	ON_WM_CAPTURECHANGED()
	ON_CONTROL_REFLECT(BN_CLICKED, &CSkinButton::OnBnClicked)
END_MESSAGE_MAP()



// CSkinButton message handlers

//=============================================================================
void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	BOOL bIsPressed  = (lpDrawItemStruct->itemState & ODS_SELECTED);
	BOOL bIsFocused  = (lpDrawItemStruct->itemState & ODS_FOCUS);
	BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);

	BOOL bCheck = GetCheck () & BST_CHECKED;
	m_pCurImg = NULL;
	if (!m_CheckedButton) {
		if (bCheck && !m_MouseOnButton)
			m_pCurImg = m_pImgDown;
		else if (bIsPressed)
			m_pCurImg = m_pImgDown;
		else if (m_MouseOnButton)
			m_pCurImg = m_pImgOver;
		else if (bIsDisabled)
			m_pCurImg = m_pImgDisabled;
		else
			m_pCurImg = m_pImgNormal;
	} else {
		if (bCheck)
			m_pCurImg = m_pImgDown;
		else
			m_pCurImg = m_pImgNormal;
	}

	UpdateSkin ();
}

void CSkinButton::OnKillFocus(CWnd* pNewWnd)
{
	__super::OnKillFocus(pNewWnd);

	// TODO: Add your message handler code here
	m_MouseOnButton = FALSE;
	UpdateSkin ();
}

void CSkinButton::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	__super::OnMouseMove(nFlags, point);

	//if (nFlags & MK_LBUTTON && !m_MouseOnButton)
	//	return;
	CWnd* pWnd = GetActiveWindow();
	CWnd* pParentWnd = GetOwner();
	if (GetCapture() != this && pWnd && pParentWnd) {
		m_MouseOnButton = TRUE;
		SetCapture();
		Invalidate ();
	} else {
		CPoint p2 (point);
		ClientToScreen(&p2);
		CWnd* wndUnderMouse = WindowFromPoint(p2);
		if (wndUnderMouse && wndUnderMouse->GetSafeHwnd() != GetSafeHwnd()) {
			if (m_MouseOnButton) {
				m_MouseOnButton = FALSE;
				Invalidate ();
			}
			if (!(nFlags & MK_LBUTTON))
				ReleaseCapture();
		}
	}
}

void CSkinButton::OnCaptureChanged(CWnd *pWnd)
{
	// TODO: Add your message handler code here
	if (m_MouseOnButton) {
		ReleaseCapture();
		Invalidate ();
	}

	__super::OnCaptureChanged(pWnd);
}

//=============================================================================
BOOL CSkinButton::SetTooltip( LPCTSTR lpszText )
{
	m_ctrlTooltip.AddTool(this, lpszText);
	m_ctrlTooltip.UpdateTipText(lpszText, this);
	m_ctrlTooltip.Activate(TRUE);

	return TRUE;
}

//=============================================================================
BOOL CSkinButton::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class
	m_ctrlTooltip.RelayEvent(pMsg);

	return __super::PreTranslateMessage(pMsg);
}

void CSkinButton::OnBnClicked()
{
	// TODO: Add your control notification handler code here
	FireEvent(GetCtrlID());
}
